home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 001-025 / 006 / compress / atob.c < prev    next >
C/C++ Source or Header  |  1995-03-13  |  2KB  |  120 lines

  1. /* atob: version 4.0
  2.  * stream filter to change printable ascii from "btoa" back into 8 bit bytes
  3.  * if bad chars, or Csums do not match: exit(1) [and NO output]
  4.  *
  5.  *  Paul Rutter        Joe Orost
  6.  *  philabs!per        petsd!joe
  7.  *  Fred Fish        (change into pure filter, always output)
  8.  */
  9.  
  10. #include <stdio.h>
  11.  
  12. #define reg register
  13.  
  14. #define streq(s0, s1)  strcmp(s0, s1) == 0
  15.  
  16. #define times85(x)    ((((((x<<2)+x)<<2)+x)<<2)+x)
  17.  
  18. long int Ceor = 0;
  19. long int Csum = 0;
  20. long int Crot = 0;
  21. long int word = 0;
  22. long int bcount = 0;
  23.  
  24. #define DE(c) ((c) - '!')
  25.  
  26. fatal() {
  27.   fprintf(stderr, "bad format or Csum to atob\n");
  28.   exit(1);
  29. }
  30.  
  31. decode(c) 
  32.   reg c;
  33. {
  34.   if (c == 'z') {
  35.     if (bcount != 0) {
  36.       fatal();
  37.     } else {
  38.       byteout(0);
  39.       byteout(0);
  40.       byteout(0);
  41.       byteout(0);
  42.     }
  43.   } else if ((c >= '!') && (c < ('!' + 85))) {
  44.     if (bcount == 0) {
  45.       word = DE(c);
  46.       ++bcount;
  47.     } else if (bcount < 4) {
  48.       word = times85(word);
  49.       word += DE(c);
  50.       ++bcount;
  51.     } else {
  52.       word = times85(word) + DE(c);
  53.       byteout((int)((word >> 24) & 255));
  54.       byteout((int)((word >> 16) & 255));
  55.       byteout((int)((word >> 8) & 255));
  56.       byteout((int)(word & 255));
  57.       word = 0;
  58.       bcount = 0;
  59.     }
  60.   } else {
  61.     fatal();
  62.   }
  63. }
  64.  
  65. byteout(c) 
  66.   reg c;
  67. {
  68.   Ceor ^= c;
  69.   Csum += c;
  70.   Csum += 1;
  71.   if ((Crot & 0x80000000)) {
  72.     Crot <<= 1;
  73.     Crot += 1;
  74.   } else {
  75.     Crot <<= 1;
  76.   }
  77.   Crot += c;
  78.   putc(c, stdout);
  79. }
  80.  
  81. main(argc, argv) 
  82.   char **argv;
  83. {
  84.   reg c;
  85.   char buf[100];
  86.   long int n1, n2, oeor, osum, orot;
  87.  
  88.   if (argc != 1) {
  89.     fprintf(stderr,"bad args to %s\n", argv[0]);
  90.     exit(2);
  91.   }
  92.   /*search for header line*/
  93.   for (;;) {
  94.     if (fgets(buf, sizeof buf, stdin) == NULL) {
  95.       fatal();
  96.     }
  97.     if (streq(buf, "xbtoa Begin\n")) {
  98.       break;
  99.     }
  100.   }
  101.  
  102.   while ((c = getchar()) != EOF) {
  103.     if (c == '\n') {
  104.       continue;
  105.     } else if (c == 'x') {
  106.       break;
  107.     } else {
  108.       decode(c);
  109.     }
  110.   }
  111.   if(scanf("btoa End N %ld %lx E %lx S %lx R %lx\n",
  112.          &n1, &n2, &oeor, &osum, &orot) != 5) {
  113.     fatal();
  114.   }
  115.   if ((n1 != n2) || (oeor != Ceor) || (osum != Csum) || (orot != Crot)) {
  116.     fatal();
  117.   }
  118.   exit(0);
  119. }
  120.